/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: ActivityTurntableDrawProxy
 * Author:   zhouheng
 * Date:     2019/6/17 21:45
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.zhouh.golden.activity.service.processor;

import com.zhouh.golden.activity.dao.ActDrawAwardMapper;
import com.zhouh.golden.activity.domain.ActDrawAward;
import com.zhouh.golden.activity.domain.ActDrawAwardItem;
import com.zhouh.golden.activity.domain.ActDrawAwardRecord;
import com.zhouh.golden.activity.dto.ActDrawAwardRecordBean;
import com.zhouh.golden.activity.service.processor.constants.DrawContants;
import com.zhouh.golden.activity.service.processor.exception.RewardException;
import com.zhouh.golden.activity.service.processor.exception.UnRewardException;
import com.zhouh.golden.activity.service.processor.reward.CashRewardProcessor;
import com.zhouh.golden.activity.service.processor.reward.JdCardRewardProcessor;
import com.zhouh.golden.activity.service.processor.reward.NoneRewardProcessor;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.swing.text.html.parser.Entity;
import java.math.BigDecimal;
import java.util.*;

/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author zhouheng
 * @create 2019/6/17
 * @since 1.0.0
 */
@Slf4j
@Service
public class ActivityTurntableDrawProxy implements ApplicationContextAware{
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    // 放大倍数
    private static final int mulriple = 10000;

    @Autowired
    private ActDrawAwardMapper actDrawAwardMapper;

    private Map<Integer,RewardProcessor> rewardProcessorMap = new HashMap<>();

    /**
     * @description: 抽奖
     * @date: 2019/6/17 21:48
     * @author:zhouheng
     */
    public void doDrawForProxy(ActivityDrawContext activityDrawContext) {
        // 检查用户剩余抽奖次数

        try {
            // 抽奖
            List<ActDrawAwardItem> actDrawAwardItems = (List<ActDrawAwardItem>) redisTemplate.opsForValue().get(DrawContants.DRAW_ITEM);
            ActDrawAwardItem actDrawAwardItem = doPlay(actDrawAwardItems);
            activityDrawContext.setActDrawAwardItem(actDrawAwardItem);

//            // 该奖项对应得奖品
            ActDrawAward actDrawAward = actDrawAwardMapper.queryAwardById(actDrawAwardItem.getAwardId());
            activityDrawContext.setActDrawAward(actDrawAward);

            rewardProcessorMap.get(actDrawAward.getAwardType()).doReword(activityDrawContext);
        }catch (UnRewardException e){
            log.info("未抽到奖品或者出现异常的情况下");
        }finally {
            log.info("ActivityTurntableDrawProxy.doDrawForProxy->{}",activityDrawContext);
        }
    }

    /**
     * @description: 
     * @date: 2019/6/17 22:19
     * @author:zhouheng
     * @param actDrawAwardItems
     */
    private ActDrawAwardItem doPlay(List<ActDrawAwardItem> actDrawAwardItems) {
        ActDrawAwardItem awardItem = null;
        if (actDrawAwardItems.isEmpty()) {
            throw new RewardException("奖项未设定或未正确初始化");
        }

        int lastScope = 0;
        // 随机打乱集合顺序
        Collections.shuffle(actDrawAwardItems);

        // 取出一个随机值作为抽奖因子
        int luckyNumber = new Random().nextInt(mulriple);

        // 存储抽奖概率集合
        Double[] drawAwardArr = {};
        Map<Integer,int[]> awardItemScope = new HashMap<>();
        for (int i = 0; i < actDrawAwardItems.size(); i++){
            int newScope = lastScope + new BigDecimal(actDrawAwardItems.get(i).getProbability().doubleValue()).multiply(new BigDecimal(mulriple)).intValue();
            awardItemScope.put(actDrawAwardItems.get(i).getId(), new int[]{lastScope,newScope});
            lastScope = newScope;
        }

        int luckyPrizeId = 0;
        for (Map.Entry<Integer,int[]> entry : awardItemScope.entrySet()){
            if (entry.getValue()[0] <= luckyNumber && entry.getValue()[1] > luckyNumber){
                luckyPrizeId = entry.getKey();
                break;
            }
        }

        // 获取中奖奖项
        int finalLuckyPrizeId = luckyPrizeId;
        Optional<ActDrawAwardItem> actDrawAwardItem = actDrawAwardItems.stream().filter(t->t.getId().equals(finalLuckyPrizeId)).findFirst();

        return actDrawAwardItem.get();
    }

    /**
     * @description: 数据初始化
     * @date: 2019/6/18 23:14
     * @author:zhouheng
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        rewardProcessorMap.put(DrawContants.AWARD_TYPE_ENUM.JD_CARD.getValue(), new JdCardRewardProcessor());
        rewardProcessorMap.put(DrawContants.AWARD_TYPE_ENUM.CASH.getValue(), new CashRewardProcessor());
        rewardProcessorMap.put(DrawContants.AWARD_TYPE_ENUM.NONE.getValue(), new NoneRewardProcessor());
    }
}